﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{
    /// <summary>
    /// Esta classe vai representar genericamente todo objeto visto na tela
    /// </summary>
    public abstract class Sprite
    {
        /// <summary>
        /// Imagem do objeto com todas as suas animações
        /// </summary>
        protected Texture2D textura;

        /// <summary>
        /// Posição do objeto na tela
        /// </summary>
        Vector2 posicao;
        public Vector2 Posicao
        {
            get { return posicao; }
            set { posicao = value; }
        }

        /// <summary>
        /// Velocidade do objeto na tela
        /// </summary>
        Vector2 velocidade;
        public Vector2 Velocidade
        {
            get { return velocidade; }
            set { velocidade = value; }
        }

        /// <summary>
        /// Retângulo de colisão com o objeto
        /// </summary>
        Rectangle colisao;
        public Rectangle Colisao
        {
            get { return new Rectangle((int)Posicao.X, (int)Posicao.Y,
                animacao_atual.quadro_X, animacao_atual.quadro_Y);
            }
            set { colisao = value; }
        }

        public void InverterVelocidadeX()
        {
            Velocidade = new Vector2(Velocidade.X * -1, Velocidade.Y);
        }

        public void InverterVelocidadeY()
        {
            Velocidade = new Vector2(Velocidade.X, Velocidade.Y * -1);
        }

        /// <summary>
        /// Para o objeto aparecer na tela ou nao
        /// </summary>
        bool visivel;
        public bool Visivel
        {
            get { return visivel; }
            set { visivel = value; }
        }

        /// <summary>
        /// Para o objeto aparecer na tela invertido na horizontal
        /// </summary>
        bool direita;
        public bool Direita
        {
            get { return direita; }
            set { direita = value; }
        }

        /// <summary>
        /// Estrutura usada para armazenar uma animação, cada classe derivada terá as suas próprias
        /// Cada animação deverá estar em uma linha
        /// </summary>
        public struct Animacao
        {
            public int quadro_X;
            public int quadro_Y;
            public int qtd_quadros;
            public int quadros_seg;
            public int Y_inicial;//atual?
            public int X_inicial;//atual?
            //frame atual? tempo update != tempo draw?
            public string nome;
            //public bool ativa;
            //public int quadro_atual;
        }
        protected Animacao animacao_atual;
        
        /// <summary>
        /// Objeto "carregador" usado no construtor
        /// </summary>
        ContentManager Content;

        /// <summary>
        /// Informações da janela
        /// </summary>
        protected GameWindow Window;

        /// <summary>
        /// Construtor padrão
        /// </summary>
        public Sprite(ContentManager Content, GameWindow Window, string str_textura)
        {
            this.Content = Content;
            this.Window = Window;
            this.Posicao = Vector2.Zero;
            this.Velocidade = Vector2.Zero;
            this.textura = Content.Load<Texture2D>(str_textura);
            this.visivel = true;
            this.direita = true;

            Animacao padrao = new Animacao();
            padrao.qtd_quadros = 1;
            padrao.quadros_seg = 1;
            padrao.X_inicial = 0;
            padrao.Y_inicial = 0;
            padrao.quadro_X = this.textura.Width;
            padrao.quadro_Y = this.textura.Height;

            animacao_atual = padrao;

        }

        /// <summary>
        /// Update padrão que todo objeto que deriva de Sprite DEVE sobrecarregar
        /// </summary>
        /// <param name="gameTime"></param>
        public abstract void Update(GameTime gameTime);

        /// <summary>
        /// Draw padrão básico de teste.
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="spriteBatch"></param>
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            if (visivel)
            {
                int frame = (int)(gameTime.TotalGameTime.TotalSeconds * animacao_atual.quadros_seg) % animacao_atual.qtd_quadros;

                spriteBatch.Draw(
                        textura,
                        new Rectangle(
                            (int)Posicao.X,
                            (int)Posicao.Y,
                            animacao_atual.quadro_X,
                            animacao_atual.quadro_Y),
                        new Rectangle(
                            frame * animacao_atual.quadro_X,
                            animacao_atual.Y_inicial,
                            animacao_atual.quadro_X,
                            animacao_atual.quadro_Y),
                        new Color(
                            1.0f,// * alfa,
                            1.0f,// * alfa,
                            1.0f,// * alfa,
                            1.0f),//alfa),
                        0.0f,//rotacao,
                        Vector2.Zero,//pivo
                        (direita) ? SpriteEffects.None : SpriteEffects.FlipHorizontally,
                        1.0f);//camada);
            }
        }
    }
}
